<script setup>
import {ElMessage, ElMessageBox} from "element-plus";
import {checkFile, uploadChunkList} from "@/api/file.js";
import {getChunkList, getHash} from "@/common/utils/utils.js";
import {baseURL} from "@/request/request.js";
//图片地址列表
const urls = defineModel('urls', {
  type: Array,
  default: () => []
})
//分片尺寸
const chuckSize = 1024 * 1024 * 5;
//插入图片
const insertImage = () => {
  ElMessageBox.prompt("", {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    inputPlaceholder: '请输入图片地址',
    inputPattern: /^(http|https):\/\/([\w.]+\/?)\S*/,
    inputErrorMessage: '请输入正确的图片地址',
  })
      .then(({value}) => {
        urls.value.push(value)
      })
      .catch(() => {
        ElMessage({
          type: 'info',
          message: '取消输入',
        })
      })
}
//文件上传
const upload = async (e) => {
  const files = e.target.files;
  if (!files.length) {
    return
  }

  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    if (!file.type.includes('image')) {
      ElMessage({
        type: 'error',
        message: `文件"${file.name}"格式错误，请上传图片类型`,
      })
      continue;
    }
    //判断文件后缀
    if (!file.name.includes('.')) {
      ElMessage({
        type: 'error',
        message: `文件"${file.name}"格式错误`,
      })
      continue;
    }

    // 处理每个文件上传
    await handleSingleFileUpload(file);
  }

  // 清空文件输入框，以便用户可以再次选择相同的文件
  e.target.value = '';
}

// 处理单个文件的上传
const handleSingleFileUpload = async (file) => {
  const chunkList = getChunkList(file, chuckSize);
  const md5 = await getHash(chunkList)
  const {data} = await checkFile(md5)

  if (data.url) {
    urls.value.push(baseURL + data.url)
    return
  }

  if (data.index) {
    await uploadChunk(file, chunkList, md5, data.index)
    return
  }

  await uploadChunk(file, chunkList, md5)
}

//分片上传
const uploadChunk = async (file, chunkList, md5, index = 0) => {
  const fileName = file.name
  const fileType = file.type
  const size = file.size
  for (index; index < chunkList.length; index++) {
    const formData = new FormData()
    formData.append('file', chunkList[index])
    formData.append('fileName', fileName)
    formData.append('fileType', fileType)
    formData.append('index', index)
    formData.append('size', size)
    formData.append('md5', md5)
    formData.append('total', chunkList.length)
    const {code, data, msg} = await uploadChunkList(formData)
    if (code === 200) {
      urls.value.push(baseURL + data.url)
      break; // 添加完URL后退出循环
    } else if (code === 400) {
      ElMessage.error(msg)
    }
  }
}

// 删除单个图片
const removeImage = (index) => {
  urls.value.splice(index, 1)
}

</script>

<template>
  <div class="content">
    <div v-if="urls.length" class="image-list">
      <div v-for="(url, index) in urls" :key="index" class="avatar">
        <el-image :src="url" :preview-src-list="urls" :initial-index="index" class="img"></el-image>
        <el-icon @click="removeImage(index)" class="close">
          <Close/>
        </el-icon>
      </div>
    </div>
    <el-button-group v-if="!urls.length">
      <el-button type="primary" class="btn">
        上传图片<input type="file" @change="upload" multiple class="upload"/>
      </el-button>
      <el-button type="warning" @click="insertImage">插入图片</el-button>
    </el-button-group>
    <el-button-group v-else>
      <el-button type="primary" class="btn">
        继续上传<input type="file" @change="upload" multiple class="upload"/>
      </el-button>
      <el-button type="warning" @click="insertImage">插入图片</el-button>
    </el-button-group>
  </div>
</template>

<style scoped lang="scss">
.content {
  position: relative;

  .image-list {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }

  .avatar {
    width: 120px;
    position: relative;

    &:hover {
      .close {
        opacity: 1;
      }
    }

    .img {
      width: 120px;
      height: 120px;
      object-fit: cover;
    }

    .close {
      position: absolute;
      right: 5px;
      top: 5px;
      cursor: pointer;
      font-size: 18px;
      opacity: 0;
      transition: opacity 0.2s;
      background-color: rgba(0, 0, 0, 0.5);
      color: white;
      border-radius: 50%;
      padding: 2px;
    }
  }

  .btn {
    position: relative;

    .upload {
      position: absolute;
      width: 100%;
      height: 100%;
      left: 0;
      top: 0;
      opacity: 0;
      cursor: pointer;
    }
  }
}
</style>
